﻿package com.winglish.as3.exam.opic 
{
	import com.winglish.as3.loader.SoundGroup;
	import com.winglish.as3.loader.SWFLoader;
	import com.winglish.as3.record.Recorder;
	
	import flash.display.SimpleButton;
	import flash.events.TimerEvent;
	import flash.text.TextField;
	import flash.utils.Timer;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	/**
	 * ...
	 * @author charmjin
	 */
	public class OpicSingle extends OpicHelp 
	{
		private var dataObj:Object = null;
		private var isAniLoaded:int = 0;
		private var isAnsLoaded:Boolean = false;
		
		private var sound:SoundGroup;
		private var swfloader:SWFLoader;
		private var reactionLoader:SWFLoader;
		
		private var recordingMc:MovieClip;
		private var msgMc:MovieClip;
		private var stateMc:MovieClip;
		private var replayBtn:SimpleButton;
		private var playMc:MovieClip;
		private var aniMc:MovieClip;
		private var equalizerMc:MovieClip;
		private var equalizerTargetMc:MovieClip;
		
		private var rePlayTimer:Timer = new Timer(1000, 5);
		private var count:uint = 0;
		private const opicTry:uint = 2;
		private var record:Recorder = new Recorder();
		
		private var ans:OpicAnswer;
		
		public function SingleOpic(data:Object){
			dataObj = data;
			testAniLoad(dataObj.testAni);
			rePlayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, rePlayTimerComplete);
			
			if(dataObj.ans){
				ans = new OpicAnswer(record, dataObj.ans);
				ans.addEventListener("ansSoundAllLoad", ansSoundAllLoadEvent);
				ans.addEventListener("soundAllStopFirst", soundAllStopFirstEvent);
				ans.soundLoad(dataObj.soundPath, dataObj.queSound, dataObj.ansSound);
			}
		}
		
		/**
		 * 테스트 애니 로드.
		 * @param	filename
		 */
		private function testAniLoad(filename:String):void {
			swfloader = new SWFLoader(dataObj.aniPath + filename);
			swfloader.addEventListener("swfLoaded", swfLoadComplete);
			swfloader.addEventListener("swfPlayEnd", swfPlayEnd); 
			reactionLoader = new SWFLoader(dataObj.aniPath + "reaction.swf");
			reactionLoader.addEventListener("swfLoaded", swfLoadComplete);
		}
		
		/**
		 * 테스트 애니 로드 완료 이벤트.
		 * @param	e
		 */
		private function swfLoadComplete(e:Event):void {
			e.target.getContent().stop();
			isAniLoaded++;
			trace("ani load");
			if (isAniLoaded == 2 && isAnsLoaded) allLoaed();
			e.target.removeEventListener(Event.INIT, swfLoadComplete);
		}
		/**
		 * 답변 페이지에 필요한 사운드 로드 완료 이벤트.
		 * @param	e
		 */
		private function ansSoundAllLoadEvent(e:Event):void {
			isAnsLoaded = true;
			if (isAniLoaded == 2 && isAnsLoaded) allLoaed();
		}
		/**
		 * 답변 페이지에서 사운드 플레이 이벤트.
		 * @param	e
		 */
		private function soundAllStopFirstEvent(e:Event):void {
			dispatchEvent(new Event("answerPlay"));
			ans.removeEventListener("soundAllStopFirst", soundAllStopFirstEvent);
		}
		/**
		 * 애니와 사운드 로드 완료.
		 */
		private function allLoaed():void {
			dispatchEvent(new Event("opicAllLoad"));
		}
		
		/**
		 * 오픽 시험에 필요한 버튼, 애니 셋팅.
		 * @param	target
		 * @param	arr
		 */
		public function init(target:MovieClip, arr:Array):void {
			for each(var i:String in arr) {
				this[i] = target[i];
				switch(i) {
					case "recordingMc" : 
						this[i].visible = false;
						break;
					case "msgMc" : 
						break;
					case "stateMc" : 
						break;
					case "replayBtn" : 
						this[i].addEventListener(MouseEvent.CLICK, replayBtnClick);
						this[i].visible = false;
						break;
					case "playMc" : 
						this[i].addEventListener(MouseEvent.CLICK, playMcClick);
						this[i].buttonMode = true;
						break;
					case "aniMc" : 
						this[i].addChild(swfloader.getContent());
						break;
					case "equalizerMc" : 
						this["equalizerTargetMc"] = target["equalizerTargetMc"];
						break;
				}
			}
		}
		
		/**
		 * play버튼 클릭 이벤트.
		 * @param	e
		 */
		private function playMcClick(e:MouseEvent):void {
			dispatchEvent(new Event("aniPlay"));
			if (msgMc && msgMc.visible) msgMc.visible = false;
			swfloader.getContent().play();
			swfloader.startEnterFrame();
			if(stateMc) stateMc.gotoAndStop(2);
			e.target.gotoAndStop(2);
			e.target.buttonMode = false;
			e.target.removeEventListener(MouseEvent.CLICK, playMcClick);
		}
		
		/**
		 * replay버튼 클릭 이벤트.
		 * @param	e
		 */
		private function replayBtnClick(e:MouseEvent):void {
			rePlayTimer.stop();
			rePlayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, rePlayTimerComplete);
			e.target.visible = false;
			playMc.visible = true;
			if(stateMc) stateMc.gotoAndStop(3);
			swfloader.getContent().play();
			swfloader.startEnterFrame();
			e.target.removeEventListener(MouseEvent.CLICK, replayBtnClick);
		}
		
		/**
		 * ani play end 이벤트.
		 * @param	e
		 */
		private function swfPlayEnd(e:Event):void {
			count++;
			if (count < opicTry) {
				replayBtn.visible = true;
				playMc.visible = false;
				rePlayTimer.start();
			}else {
				replayBtn.visible = false;
				playMc.visible = true;
				rePlayTimer.reset();
				rec();
			}
		}
		
		/**
		 * replayTimer Complete 이벤트.
		 * @param	e
		 */
		private function rePlayTimerComplete(e:TimerEvent):void {
			replayBtn.visible = false;
			playMc.visible = true;
			rec();
		}
		
		/**
		 * 녹음 기능.
		 */
		private function rec():void {
			if(recordingMc) recordingMc.visible = true;
			record.start();
			
			if(stateMc) stateMc.gotoAndStop(4);
			aniMc.addChild(reactionLoader.getContent());
			reactionLoader.getContent().play();
			if (equalizerMc) addEventListener(Event.ENTER_FRAME, recordingEvent);
			
			var recTimer:Timer = new Timer(1000, 90);
			recTimer.addEventListener(TimerEvent.TIMER_COMPLETE, recTimerEnd);
			recTimer.start();
			
			dispatchEvent(new Event("recording"));
		}
		
		/**
		 * 녹음 끝 이벤트
		 * @param	e
		 */
		private function recTimerEnd(e:TimerEvent):void {
			if(stateMc) stateMc.gotoAndStop(5);
			e.target.removeEventListener(TimerEvent.TIMER_COMPLETE, recTimerEnd);
		}
		
		/**
		 * 이퀄라이져에 필요한 enterFrame 이벤트.
		 * @param	e
		 */
		private function recordingEvent(e:Event):void {
			var num:Number = record.getLev();
            if (equalizerMc) equalizerMc.y = equalizerTargetMc.y + equalizerTargetMc.height - num;
		}
		
		/**
		 * 녹음완료 버튼 셋팅.
		 * @param	btn
		 */
		public function setRecordingEndMc(mc:MovieClip):void {
			mc.addEventListener(MouseEvent.CLICK, recordingEndMcClick);
			mc.buttonMode = true;
		}
		
		
		/**
		 * 녹음완료 버튼 클릭 이벤트.
		 * @param	e
		 */
		private function recordingEndMcClick(e:MouseEvent):void {
			record.stop();
			if (equalizerMc) removeEventListener(Event.ENTER_FRAME, recordingEvent);
			dispatchEvent(new Event("recordingEndClick"));
		}
		
		/**
		 * 질문, 나의 답변, 답변 재녹음, 모범 답변 관련 버튼 셋팅.
		 * @param	path
		 */
		public function setAnsBtn(path:MovieClip):void {
			ans.setBtn(path);
		}
		
		/**
		 * 문제 텍스트 셋팅. 
		 * @param	path 문제 텍스트의 무비클립.
		 * @param	eng 영문 텍스트 필드.
		 * @param	kor 한글 텍스트 필드.
		 */
		public function setQustionTxt(path:MovieClip, eng:TextField, kor:TextField = null):void {
			ans.setQustionTxt(path, eng, kor);
		}
		
		/**
		 * 답변 텍스트 셋팅.
		 * @param	path 문제 텍스트의 무비클립.
		 * @param	eng 영문 텍스트 필드.
		 * @param	kor 한글 텍스트 필드.
		 * @param   strategy 전략 텍스트 필드.
		 * @param   voca 단어 텍스트 필드.
		 */
		public function setAnswerTxt(path:MovieClip, eng:TextField, kor:TextField, strategy:TextField = null, voca:TextField = null) :void{
			ans.setAnswerTxt(path, eng, kor, strategy, voca);
		}
	}

}